'''
图像内容理解与Base64编码传输示例

核心功能：使用Base64编码将图像数据直接嵌入请求，避免URL访问问题

技术亮点：
1. Base64图像编码：将图像转换为文本格式传输
2. 离线图像处理：不依赖外部URL可访问性
3. 安全保障：避免网络传输中的图片丢失或篡改
'''

import base64
import os

import httpx
from dotenv import load_dotenv
from langchain_core.messages import HumanMessage
from langchain_openai import ChatOpenAI

# 自动加载 .env 文件中的环境变量
load_dotenv()

# ========== 初始化视觉语言模型 ==========
'''
视觉语言模型配置说明：
- VL模型：具备视觉理解能力的多模态模型
- streaming: 虽然设为True，但单次调用中不体现流式特性
- temperature=0: 确保图像描述的准确性和一致性
'''
llm = ChatOpenAI(api_key=os.getenv("MODELSCOPE_API_KEY"), openai_api_base=os.getenv("MODELSCOPE_API_BASE"), model="Qwen/Qwen2.5-VL-72B-Instruct", streaming=True, temperature=0)
# ========== 图像数据准备与Base64编码 ==========
'''
Base64编码的优势：
✅ 可靠性：不依赖外部URL的可访问性
✅ 安全性：避免网络传输中的中间人攻击
✅ 完整性：确保图像数据完整传递
✅ 离线支持：可在无网络环境中使用本地图片

适用场景：
- 内部系统图片处理
- 敏感图片内容分析
- 网络环境不稳定的情况
- 需要确保图片完整性的场景
'''
# 在线图片地址（作为数据源）
image_url = "https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fimage109.360doc.com%2FDownloadImg%2F2025%2F04%2F0321%2F296122601_4_20250403090445718&refer=http%3A%2F%2Fimage109.360doc.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1762504985&t=8090aac3171f1a36b1433b4888b8722f"

print("🖼️ 图像处理流程:")
print(f"   源图片URL: {image_url}")

try:
    # 步骤1: 通过HTTP请求获取图片二进制数据
    print("📥 下载图片数据...")
    image_response = httpx.get(image_url)
    image_response.raise_for_status()  # 检查HTTP请求是否成功

    # 步骤2: 将图片二进制数据转换为Base64编码字符串
    print("🔧 进行Base64编码...")
    image_data = base64.b64encode(image_response.content).decode("utf-8")

    # 步骤3: 计算数据大小信息
    original_size = len(image_response.content)  # 原始二进制数据大小
    encoded_size = len(image_data)  # Base64编码后大小
    size_increase = (encoded_size - original_size) / original_size * 100

    print(f"✅ 图片处理完成:")
    print(f"   原始大小: {original_size} 字节")
    print(f"   Base64后: {encoded_size} 字节")
    print(f"   大小增加: {size_increase:.1f}% (Base64编码特性)")

except httpx.HTTPError as e:
    print(f"❌ 图片下载失败: {e}")
    exit(1)
except Exception as e:
    print(f"❌ 图片处理异常: {e}")
    exit(1)

# ========== 多模态消息格式规范 ==========
'''
标准消息格式说明：

固定写法：
{
    "type": "text",                    # 文本类型
    "text": "文本内容"                 # 具体的文本指令
}

{
    "type": "image_url",               # 图像类型  
    "image_url": {
        "url": "图片URL或base64数据"   # 支持URL和Base64两种格式
    }
}

官方文档参考：https://python.langchain.com/docs/how_to/

Base64数据URL格式：
"data:image/[格式];base64,[Base64编码数据]"

支持的图片格式：
- JPEG: data:image/jpeg;base64,...
- PNG:  data:image/png;base64,...
- WebP: data:image/webp;base64,...
- GIF:  data:image/gif;base64,...

多内容类型示例：
content = [
    {"type": "text", "text": "指令"},
    {"type": "image_url", "image_url": {"url": "url1"}},
    {"type": "image_url", "image_url": {"url": "data:image/jpeg;base64,..."}}
]
'''

# ========== 构建Base64图像消息 ==========
'''
消息设计策略：
1. 明确的文本指令：指定输出语言、内容和长度限制
2. Base64图像数据：直接嵌入图像内容，确保可靠性
3. 格式规范：严格遵循多模态消息格式标准
'''
message = HumanMessage(
    content=[
        # 文本指令：明确任务要求
        {
            "type": "text",
            "text": "用中文描述这种图片中的天气,请不要超过40个字"
            # 指令解析：
            # - "用中文": 指定输出语言
            # - "描述天气": 明确分析维度
            # - "不超过40个字": 控制输出长度
        },

        # Base64图像数据：可靠的内容传输方式
        {
            "type": "image_url",
            "image_url": {
                "url": f"data:image/jpeg;base64,{image_data}"
                # 数据URL格式：data:[MIME类型];base64,[编码数据]
            }
        }

        # 备选方案：直接使用URL（当URL可靠时）
        # {"type": "image_url", "image_url": {"url": image_url}}
    ],
)

print("\n📨 构建的多模态消息详情:")
print(f"   文本指令: '{message.content[0]['text']}'")
print(f"   图像格式: Base64编码 (JPEG)")
print(f"   数据大小: {len(image_data)} 字符")
print(f"   传输方式: 内嵌数据 (无需外部URL访问)")

# ========== 调用模型进行图像理解 ==========
print("\n🚀 开始调用视觉语言模型分析图像...")
print("⏳ 模型正在解析Base64图像数据并理解内容...")

try:
    response = llm.invoke([message])

    print("✅ 图像分析完成!")
    print("\n📊 天气分析结果:")
    print("=" * 50)
    print(response.content)
    print("=" * 50)

    # 分析输出是否符合要求
    word_count = len(response.content.strip())
    print(f"\n📝 输出统计:")
    print(f"   字数: {word_count} {'✅' if word_count <= 40 else '❌ 超出限制'}")
    print(f"   语言: 中文 ✅")

except Exception as e:
    print(f"❌ 模型调用失败: {e}")


# ========== Base64 vs URL 传输方式对比 ==========
def demonstrate_transmission_comparison():
    """
    演示Base64和URL传输方式的对比
    """
    print("\n" + "=" * 60)
    print("🔍 Base64 vs URL 传输方式对比")
    print("=" * 60)

    comparison_data = [
        {
            "aspect": "可靠性",
            "base64": "✅ 不依赖网络可达性",
            "url": "❌ 依赖URL可访问性"
        },
        {
            "aspect": "安全性",
            "base64": "✅ 数据完整嵌入",
            "url": "⚠️  可能被中间人篡改"
        },
        {
            "aspect": "性能",
            "base64": "❌ 数据体积增加约33%",
            "url": "✅ 传输数据量小"
        },
        {
            "aspect": "适用场景",
            "base64": "内部系统、敏感数据",
            "url": "公开图片、网络良好环境"
        }
    ]

    print("\n📊 传输方式对比表:")
    for item in comparison_data:
        print(f"   {item['aspect']}:")
        print(f"      Base64: {item['base64']}")
        print(f"      URL:    {item['url']}")


# ========== 实际业务应用场景 ==========
def demonstrate_business_applications():
    """
    演示Base64图像处理的实际业务应用
    """
    print("\n" + "=" * 60)
    print("🏢 Base64图像处理的业务应用场景")
    print("=" * 60)

    applications = [
        {
            "name": "医疗影像分析",
            "description": "分析X光片、CT扫描等医学影像",
            "use_base64": "✅ 患者隐私数据需要安全传输",
            "prompt": "分析这张医学影像，描述异常发现"
        },
        {
            "name": "证件识别验证",
            "description": "识别身份证、护照等证件信息",
            "use_base64": "✅ 敏感个人信息需要保护",
            "prompt": "提取这张证件图片中的文字信息"
        },
        {
            "name": "工业质检",
            "description": "检测产品缺陷和质量问题",
            "use_base64": "✅ 内部生产数据需要保密",
            "prompt": "检测这张产品图片中的缺陷"
        },
        {
            "name": "安防监控",
            "description": "分析监控摄像头画面",
            "use_base64": "✅ 监控数据需要完整保存",
            "prompt": "描述监控画面中的人员活动"
        }
    ]

    print("\n💼 业务应用示例:")
    for app in applications:
        print(f"   🔹 {app['name']}:")
        print(f"      描述: {app['description']}")
        print(f"      Base64优势: {app['use_base64']}")
        print(f"      典型提示词: '{app['prompt']}'")
        print()


# ========== 性能优化建议 ==========
def demonstrate_optimization_tips():
    """
    演示Base64图像处理的性能优化建议
    """
    print("\n" + "=" * 60)
    print("⚡ Base64图像处理优化建议")
    print("=" * 60)

    print("\n🖼️ 图像预处理优化:")
    print("   1. 📏 尺寸调整: 将大图缩放至合适尺寸（如1024x1024）")
    print("   2. 💾 格式选择: 使用JPEG格式平衡质量和大小")
    print("   3. 🗜️ 质量压缩: 适当降低JPEG质量（如85%）")
    print("   4. 🔄 缓存机制: 对相同图片缓存Base64编码结果")

    print("\n🔧 技术实现优化:")
    print("   1. 🚀 异步处理: 使用异步请求提高并发性能")
    print("   2. ⏱️ 超时设置: 合理设置HTTP请求超时时间")
    print("   3. 🔍 错误重试: 实现网络错误的自动重试机制")
    print("   4. 📊 监控日志: 记录处理时间和数据大小")

    print("\n🎯 业务逻辑优化:")
    print("   1. ✂️ 内容裁剪: 只传输需要分析的图片区域")
    print("   2. 🎨 多图策略: 重要图片用Base64，普通图片用URL")
    print("   3. 🔄 混合传输: 根据网络条件动态选择传输方式")
    print("   4. 💰 成本考虑: 平衡传输成本和安全需求")


# ========== 扩展功能：本地图片处理 ==========
def demonstrate_local_image_processing():
    """
    演示本地图片的Base64处理流程
    """
    print("\n" + "=" * 60)
    print("💾 本地图片Base64处理演示")
    print("=" * 60)

    print("\n📁 本地图片处理流程:")
    print("   1. 读取本地图片文件")
    print("   2. 转换为二进制数据")
    print("   3. 进行Base64编码")
    print("   4. 构建数据URL")
    print("   5. 发送给视觉模型")

    # 伪代码示例
    local_image_processing = """
# 本地图片Base64处理示例代码：
import base64

# 读取本地图片
with open("local_image.jpg", "rb") as image_file:
    image_binary = image_file.read()

# Base64编码
image_base64 = base64.b64encode(image_binary).decode("utf-8")

# 构建消息
message = HumanMessage(
    content=[
        {"type": "text", "text": "分析这张本地图片"},
        {"type": "image_url", "image_url": {
            "url": f"data:image/jpeg;base64,{image_base64}"
        }}
    ]
)
"""
    print("   示例代码已准备就绪")


# 运行进阶演示
demonstrate_transmission_comparison()
demonstrate_business_applications()
demonstrate_optimization_tips()
demonstrate_local_image_processing()

print("\n" + "=" * 60)
print("🎉 Base64图像理解演示完成!")
print("=" * 60)
print("💡 核心技术总结:")
print("   1. 🔐 Base64编码确保图像传输可靠性")
print("   2. 🖼️  数据URL格式标准化图像传输")
print("   3. 🌐 摆脱外部URL访问依赖")
print("   4. 📝 明确的指令设计提升分析质量")
print("   5. 🏢 广泛适用于敏感和内部数据处理场景")